/***************************************************************************
 *   Copyright (C) 2008 by Dmitry Malakhov                                 *
 *   abr_mail@mail.ru                                                      *
 *                                                                         *
 *   This file is part of game Fifteens                                    *
 *                                                                         *
 *   Fifteens is free software; you can redistribute it and/or modify      *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   Fifteens is distributed in the hope that it will be useful,           *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

/*crypt.c*/

#include "crypt.h"
#include <string.h>
#include <stdlib.h>

t_ciph_string tciph(t_ciph_string string)
{
	int i, len, len_res;
	t_ciph_string result, buf;
	unsigned char res[64], c[1];

	len_res = 0;
	result.str = (char*)malloc(1 * sizeof(char));
	buf.str = (char*)malloc(64 * sizeof(char));
	buf.length = 64;
	for (i = 0; i < string.length; i += 64)
	{
		len = (string.length - i > 64) ? 64 : string.length - i;
		memcpy(buf.str, string.str + i, len);

		len_res += 64;

		memcpy(res, ciph(buf, len, 64).str, 64);

		result.str = (char*)realloc(result.str, (++len_res) * sizeof(char));
		memcpy(result.str + len_res - 65, res, 64);

		c[0] = (unsigned char)len;
		memcpy(result.str + len_res - 1, &c, 1);

		result.length = len_res;
	}
	return result;
}

t_ciph_string tdeciph(t_ciph_string string)
{
	int i;
	unsigned char c[1];
	t_ciph_string result, buf;

	result.str = (char*)malloc(1 * sizeof(char));
	buf.str = (char*)malloc(65 * sizeof(char));
	buf.length = 65;
	for (i = 0; i < string.length; i += 65)
	{
		memcpy(buf.str, string.str + i, 65);
		c[0] = (char)(buf.str[64]);
		result.str = (char*)realloc(result.str, (i + (int)c[0]) * sizeof(char));
		memcpy(result.str + i, deciph(buf, (int)c[0], 64).str, (int)c[0]);
		result.length = (int)c[0] + i;
	}
	return result;
}

t_ciph_string ciph(t_ciph_string string, int len, int l)
{
	int i;
	unsigned char rnd[1], c[1];
	t_ciph_string result;
	result.str = (char*)malloc(l * sizeof(char));
	result.length = l;
	for (i = 0; i < len; i++)
	{
		if (i == 0)
			c[0] = string.str[i] + l;
		else
			c[0] = string.str[i] + l + result.str[i - 1] / l;
		memcpy(result.str + i, c, 1);
	}
	for (i = len; i < l; i++)
	{
		rnd[0] = rand()%255;
		memcpy(result.str + i, rnd, 1);
	}
	for (i = l - 1; i >= 0; i--)
	{
		if (i == l - 1)
			c[0] = result.str[i] + l;
		else
			c[0] = result.str[i] + l + result.str[i + 1] / l;
		memcpy(result.str + i, c, 1);
	}
	return result;
}

t_ciph_string deciph(t_ciph_string string, int len, int l)
{
	int i;
	unsigned char c[1];
	t_ciph_string result;
	result.str = (char*)malloc(l * sizeof(char));
	for (i = 0; i < l; i++)
	{
		if (i == l - 1)
			c[0] = string.str[i] - l;
		else
			c[0] = string.str[i] - l - string.str[i + 1] / l;
		memcpy(result.str + i, c, 1);
	}
	for (i = len - 1; i >= 0; i--)
	{
		if (i == 0)
			c[0] = result.str[i] - l;
		else
			c[0] = result.str[i] - l - result.str[i - 1] / l;
		memcpy(result.str + i, c, 1);
	}
	result.str = (char*)realloc(result.str, len * sizeof(char));
	result.length = len;
	return result;
}
